package cn.lkk.samples.lang.fundamental;

import static cn.lkk.utils.PrintUtils.printExpressionResult;

/**
 * 演示 String 的基本使用
 */
public class Strings {
    public static void main(String[] args) {
        basic();
        subStrings();
        contenation();
        stringPool();
        equalityTest();
        nullAndEmptyTest();
    }

    /**
     * 字符串的创建，字符串是一串Unicode的集合
     */
    public static void basic() {
        String emptyString = "";//空字符串
        String greeting = "Hello";
        String containUnicode = "Java\u2212";

        printExpressionResult("emptyString", emptyString);
        printExpressionResult("greeting", greeting);
        printExpressionResult("containUnicode", containUnicode);
    }

    /**
     * 演示使用String.subString()函数获取子字符串
     */
    public static void subStrings() {
        String greeting = "Hello";
        int start = 0;
        int end = 3;

        //截取[start,end)部分，索引从0开始，输出 Hel
        String sub = greeting.substring(start, end);
        //两个参数相减得到的就是子串的长度
        int length = end - start;

        System.out.println(sub + " : " + length);
    }

    /**
     * 演示字符串连接
     */
    public static void contenation() {

        //使用 + 符号连接两个字符串
        String expletive = "Expletive";
        String PG13 = "deleted";
        String message = expletive + PG13;
        System.out.println(message);

        //也可以连接字符串和其他类型，非字符串的值会被转换成字符串
        int age = 13;
        String rating = "PG" + age;
        System.out.println(rating);

    }

    /**
     * 演示字符串池
     */
    public static void stringPool() {
        String s1 = "Hello";    //在池中创建一个 "Hello"
        String s2 = "Hello";    //引用刚刚的同一个字符串对象
        String s3 = new String("Hello");    //在其他地方创建一个字符串
        String s4 = "Hello!".substring(0, 5);//字符串截取的结果具体存放在哪里依赖于虚拟机的实现，可能在字符串池中，也可能不在

        printExpressionResult("s1=s2", s1 == s2);
        printExpressionResult("s1=s3", s1 == s3);
        printExpressionResult("s1=s4", s1 == s4);

        s3 = s3.intern();       //将字符串放到池中，池中已经存在了，所以直接引用该对象
        printExpressionResult("s1=s3", s1 == s3);
    }

    /**
     * 字符串的相等性比较
     */
    public static void equalityTest() {
        String s1 = "str";
        String s2 = "Str";
        System.out.println(s1.equals(s2));//比较字符串值使用equals
        System.out.println(s1.equalsIgnoreCase(s2));//忽略大小写比较字符串值
        System.out.println(s1 == s2);   //不应该使用这种方式比较两个字符串的大小，结果依赖于具体的JVM实现
    }

    /**
     * 非空检验
     */
    public static void nullAndEmptyTest() {
        String s = "value";

        //非空检验方式
        if (s != null && s.length() != 0) {
            System.out.println("The string is not empty!");
        }
    }

    /**
     * 使用连接进行构造字符串是十分低效，所以应该使用 StringBuilder 进行字符串的构造
     *
     * @see cn.lkk.samples.apis.StringBuilderAPI
     */
    public static void buildStrings() {
        //todo：验证连接和StringBuilder的性能差异
    }
}
